A typical computer application program performs three functionally distinct types of operations (presentation, application processing and data management), although operations of these types may be intermingled within the program. Presentation includes inputting data values from a user and/or providing outputs to the user, typically via a user interface. Application processing (sometimes called application logic or business logic) involves executing one or more algorithms that may use the user input values, and possibly data obtained from a data manager, to generate the outputs provided to the user and/or outputs that are then stored by the data manager. The data manager reads and/or writes persistent data stored on a storage device, manages files and the like.
Typical computer programming languages include instructions for performing each of these types of operations. Generalized examples include: GET and PUT (presentation); +, −, *, /, IF, WHILE and GOTO (application processing); and OPEN, CLOSE, SELECT, READ, WRITE and COMMIT (data management). Some statements may involve instructions of two or more of these three types. For example: “IF EXISTS MyFile.txt (ECHO The file already exists)” requires the data manager to ascertain whether a file named “MyFile.txt” exists before the IF instructions conditionally causes the ECHO instruction to display a message on a user interface.
Many application programs, which we here call “legacy applications,” have been written in a way that requires executing application logic and presentation instructions of the application on a single computer, i.e., a way that prevents splitting application logic and presentation between two separate computers or between two separately scheduled processes on a single computer (for simplicity, collectively herein referred to as two separate computers). A legacy application may access data stored on a separate server. However, a legacy application is typically written to be executed synchronously, because the application logic and the presentation are executed by a single computer. Consequently, the application logic must stall waiting for user input. “Synchronous” in the context of these legacy applications means that the application logic processing stalls while waiting for user input. Thus, a typical flow of control includes: (1) application logic processing (such as initialization); (2) a stall waiting for a user input; (3) application logic processing of data input by the user; (4) another stall waiting for a subsequent user input; (5) application logic processing of the subsequent data input by the user; etc., possibly ending with a transfer of control (loop) back to an earlier portion of application logic. A more general definition of synchronous is presented below. Examples of legacy applications include applications written in Lotus Notes, Microsoft Office and some programs written in Visual Basic, etc.
Modern applications have been written using a different model in which a presentation layer is executed by one computer, typically a client, and application logic is executed by another computer, such a server. Sometimes the server also acts as a data management server to the application; sometimes a separate server performs the data management function.
The application logic on the server often simultaneously serves several users, each user having an associated client, and each user potentially being at a different stage in the application logic processing. However, while waiting for input from one of the users, the application logic cannot stall the other users' application logic processing. Thus, modern applications are often written according to an asynchronous model, in that the application logic does not stall while waiting for user input. Instead, the application logic is written as a series of routines, and each routine handles a single user input. Each routine is invoked after its corresponding user input becomes available. While waiting for user input, context information particular to the user or the user's “session” is stored. When the user input becomes available, this context information is restored, and the appropriate routine begins executing.
Writing asynchronous applications is considered by many practitioners to be considerably more difficult than writing synchronous applications. Converting a legacy synchronous applications to an asynchronous application typically requires a manual rewriting of the legacy application by a highly skilled programmer.